﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Web;
using System.Threading;
using mshtml;
using System.Xml;

namespace StudyAT
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("user32.dll")]
        static extern bool SetCursorPos(int X, int Y);
        [DllImport("user32.dll")]
        static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, UIntPtr extraInfo);
        [Flags]
        enum MouseEventFlag : uint
        {
            Move = 0x0001,
            LeftDown = 0x0002,
            LeftUp = 0x0004,
            RightDown = 0x0008,
            RightUp = 0x0010,
            MiddleDown = 0x0020,
            MiddleUp = 0x0040,
            XDown = 0x0080,
            XUp = 0x0100,
            Wheel = 0x0800,
            VirtualDesk = 0x4000,
            Absolute = 0x8000
        }

        private List<string> course = new List<string>();
        private List<HtmlElement> chapter = new List<HtmlElement>();
        int chapterNum_current = 0;
        int courseNum_current = 0;

        private void Form1_Load(object sender, EventArgs e)
        {
            //this.webBrowser1.Navigate(this.textBox1.Text.Trim());  
            if (MessageBox.Show("是否立即清理浏览器缓存？", "清理浏览器缓存", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
            {
                try
                {
                    RunCmd("RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 8");
                }
                catch (Exception)
                {
                    MessageBox.Show("清除IE缓存失败，请手动清除。");

                }
            }

        }

        void RunCmd(string cmd)
        {
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = "cmd.exe";
            // 关闭Shell的使用
            p.StartInfo.UseShellExecute = false;
            // 重定向标准输入
            p.StartInfo.RedirectStandardInput = true;
            // 重定向标准输出
            p.StartInfo.RedirectStandardOutput = true;
            //重定向错误输出
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.CreateNoWindow = true;
            appendLog("执行清除IE缓存。");
            p.Start();
            p.StandardInput.WriteLine(cmd);
            p.StandardInput.WriteLine("exit");

        }

        /// <summary>
        /// 向richtextBox添加信息
        /// </summary>
        /// <param name="info"></param>
        private void appendLog(string info)
        {
            if (this.richTextBox1.TextLength > 60000)
            {
                this.richTextBox1.Clear();
            }
            this.richTextBox1.AppendText("[" + DateTime.Now.ToLongTimeString() + "]" + info + "\n");
        }
        /// <summary>
        /// 加载课程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                foreach (HtmlElement archor in this.webBrowser1.Document.Window.Frames["index_cont"].Document.Links)
                {
                    if (archor.GetAttribute("title").Contains("点击学习课程"))
                    {
                        //this.richTextBox1.AppendText(archor.Parent.Parent.Parent.Children[15].InnerHtml);
                        if (!archor.Parent.Parent.Parent.Children[15].InnerHtml.Contains("已完成"))
                        {
                            ListViewItem lvi = new ListViewItem("《" + archor.Parent.Parent.Parent.Children[1].InnerText + "》(" + archor.Parent.Parent.Parent.Children[11].InnerText + "学分)");
                            lvi.Tag = HttpUtility.HtmlDecode(Search_string(archor.OuterHtml, "openPlayer('", "');"));
                            this.listView1.Items.Add(lvi);

                        }

                    }
                }
                //显示共多少课
                this.label4.Text = "(" + this.listView1.Items.Count.ToString() + ")";
            }
            catch (Exception)
            {
                MessageBox.Show("请先进入“我的学习”页面并等待页面完全打开");
            }

        }

        /// <summary>
        /// 开始学习
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {

            if (this.listView1.Items.Count > 0)
            {
                this.webBrowser1.Navigate(this.listView1.Items[0].Tag.ToString());
                //打开第一课程，等待一定时间以便文档加载完成; 加载完成后，设置开始章节
                this.timer_loadPage.Enabled = true;
                this.button1.Enabled = false;
                //archor.SetAttribute("target", "_self");
                //this.webBrowser1.Navigate(this.textBox1.Text.Trim());
                this.richTextBox1.Clear();
                appendLog("开始学习" + this.listView1.Items[0].Text + "！");
            }
            else
            {
                MessageBox.Show("请先加载课程！");
            }

        }
        /// <summary>
        /// 设置开始章节
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_loadPage_Tick(object sender, EventArgs e)
        {
            this.timer_loadPage.Enabled = false;
            setStartChapter();

        }
        /// <summary>
        /// 确定开始章节
        /// </summary>
        private void setStartChapter()
        {
            //重置当前章节
            chapterNum_current = 0;

            //MessageBox.Show(main.Body.InnerHtml);
            try
            {
                //每次都需要重新获取网页元素，因为其每次都刷新
                HtmlDocument leftBar = this.webBrowser1.Document.Window.Frames["leftFrame"].Document;
                HtmlDocument topBar = this.webBrowser1.Document.Window.Frames["topFrame"].Document;
                HtmlDocument mainFrame = this.webBrowser1.Document.Window.Frames["MainFrame"].Document;

                //屏蔽定所有弹出弹出窗口
                preventPopup(leftBar);
                preventPopup(topBar);
                preventPopup(mainFrame);


                //得到所有未学完章节
                foreach (HtmlElement span in leftBar.GetElementsByTagName("SPAN"))
                {
                    if (span.InnerText != null)
                    {
                        //folderOpen_1.gif：学了一部分；folderOpen_2.gif：学完；folderOpen.gif：未学
                        if (span.Parent.Parent.Children[2].InnerHtml.Contains("folderOpen_2.gif") || span.Parent.Parent.Children[2].InnerHtml.Contains("folderOpen_1.gif") || span.Parent.Parent.Children[2].InnerHtml.Contains("folderOpen.gif"))
                        {
                            //this.richTextBox1.AppendText(span.Parent.Parent.Children[2].InnerHtml);
                            if (span.Parent.Parent.Children[2].InnerHtml.Contains("folderOpen_1.gif") || span.Parent.Parent.Children[2].InnerHtml.Contains("folderOpen.gif"))
                            {
                                //发现第一个未学完的章节，即跳转到该章节
                                span.InvokeMember("click");
                                //MessageBox.Show("Test");
                                appendLog("定位到第" + (chapterNum_current + 1).ToString() + "章节。");
                                break;

                            }
                            //获取第一个开始学习的章节
                            chapterNum_current++;

                        }
                    }
                }

            }
            catch (Exception) //如果没有设定成功，尝试再次设定起始章节
            {
                this.timer_loadPage.Enabled = true;
                appendLog("定位起始章节失败，尝试重新定位...");
                return;
            }


            //开始定时保存学习进度
            this.timer_saveStudy.Enabled = true;
            //开始切换章节
            this.timer_switchChapter.Interval = int.Parse(this.numericUpDown1.Value.ToString()) * 60 * 1000;
            this.timer_switchChapter.Enabled = true;
            //this.richTextBox1.AppendText(chapterNum_current.ToString());

        }
        private void timer_saveStudy_Tick(object sender, EventArgs e)
        {
            saveStudy();
            //Random rd = new Random();
            //this.timer_saveStudy.Interval = rd.Next(60000, 90000);

        }

        /// <summary>
        /// 切换章节
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_switchChapter_Tick(object sender, EventArgs e)
        {
            switchChapter();
        }
        /// <summary>
        /// 切换章节
        /// </summary>
        private void switchChapter()
        {
            chapter.Clear();

            try
            {
                //每次都需要重新获取网页元素，因为其每次都刷新
                HtmlDocument leftBar = this.webBrowser1.Document.Window.Frames["leftFrame"].Document;
                HtmlDocument topBar = this.webBrowser1.Document.Window.Frames["topFrame"].Document;
                HtmlDocument mainFrame = this.webBrowser1.Document.Window.Frames["mainFrame"].Document;

                //this.richTextBox1.AppendText(this.webBrowser1.Document.Window.Frames["leftFrame"].Document.GetElementsByTagName("SPAN").Count.ToString());
                //this.richTextBox1.AppendText("\r\n");
                //this.richTextBox1.AppendText(mainFrame.Body.InnerHtml);

                //屏蔽定所有弹出弹出窗口
                preventPopup(leftBar);
                preventPopup(topBar);
                preventPopup(mainFrame);


                //得到所有章节
                foreach (HtmlElement span in leftBar.GetElementsByTagName("SPAN"))
                {
                    if (span.InnerText != null)
                    {
                        //folderOpen_1.gif：学了一部分；folderOpen_2.gif：学完；folderOpen.gif：未学
                        //this.richTextBox1.AppendText(span.Parent.Parent.Children[2].InnerHtml);
                        if (span.Parent.Parent.Children[2].InnerHtml.Contains("folderOpen_2.gif") || span.Parent.Parent.Children[2].InnerHtml.Contains("folderOpen_1.gif") || span.Parent.Parent.Children[2].InnerHtml.Contains("folderOpen.gif"))
                        {
                            chapter.Add(span);
                        }
                    }
                }


                chapterNum_current++;
                //判断该章节是否已学完
                for (int i = chapterNum_current; i < chapter.Count; i++)
                {
                    if (chapter[i].Parent.Parent.Children[2].InnerHtml.Contains("folderOpen_2.gif"))
                        chapterNum_current++;
                    else
                        break;

                }

                if (chapterNum_current < chapter.Count)
                {
                    appendLog("自动跳转到第" + (chapterNum_current + 1).ToString() + "章节。");
                    chapter[chapterNum_current].InvokeMember("click");
                }
                else//如果该课程学习完成
                {
                    //停止保存进度
                    this.timer_saveStudy.Enabled = false;
                    //停止切换章节
                    this.timer_switchChapter.Enabled = false;
                    //重置当前章节
                    chapterNum_current = 0;

                    courseNum_current++;
                    if (courseNum_current < this.listView1.Items.Count)
                    {
                        topBar.InvokeScript("exitStudy");
                        appendLog("正在退出当前课程，请稍后。");
                        //等待一定时间后打开新的课程
                        timer_exitCourse.Enabled = true;
                    }
                    else
                    {
                        topBar.InvokeScript("exitStudy");
                        appendLog("本次学习完成。");
                    }
                }
            }
            catch (Exception)
            {
                appendLog("自动切换章节失败，尝试重新切换...");
            }

        }
        /// <summary>
        /// 退出当前课程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_exitCourse_Tick(object sender, EventArgs e)
        {
            this.timer_exitCourse.Enabled = false;

            this.webBrowser1.Dispose();

            this.webBrowser1 = new System.Windows.Forms.WebBrowser();

            this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.webBrowser1.Location = new System.Drawing.Point(0, 0);
            this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);
            this.webBrowser1.Name = "webBrowser1";
            this.webBrowser1.ScriptErrorsSuppressed = true;

            this.panel2.Controls.Add(this.webBrowser1);
            appendLog("开始学习《" + this.listView1.Items[courseNum_current].Text + "》！");
            this.webBrowser1.Navigate(this.listView1.Items[courseNum_current].Tag.ToString());
            //开始等待新课程加载完成
            this.timer_loadPage.Enabled = true;

        }

        /// <summary>
        /// 保存学习进度并退出
        /// </summary>
        private void saveStudyExit()
        {
            try
            {
                HtmlDocument leftBar = this.webBrowser1.Document.Window.Frames["leftFrame"].Document;
                HtmlDocument topBar = this.webBrowser1.Document.Window.Frames["topFrame"].Document;
                HtmlDocument mainFrame = this.webBrowser1.Document.Window.Frames["MainFrame"].Document;

                //屏蔽定所有弹出弹出窗口
                preventPopup(leftBar);
                preventPopup(topBar);
                preventPopup(mainFrame);

                topBar.InvokeScript("exitStudy");
                appendLog("重置完成完成。");

                //MessageBox.Show("Test");

            }
            catch (Exception)
            {
                appendLog("重置失败，session可能丢失，一般是网络或服务器问题！可能需要重新运行该软件！");
            }

        }


        /// <summary>
        /// 保存学习进度
        /// </summary>
        private void saveStudy()
        {
            try
            {
                HtmlDocument leftBar = this.webBrowser1.Document.Window.Frames["leftFrame"].Document;
                HtmlDocument topBar = this.webBrowser1.Document.Window.Frames["topFrame"].Document;
                HtmlDocument mainFrame = this.webBrowser1.Document.Window.Frames["MainFrame"].Document;

                //屏蔽定所有弹出弹出窗口
                preventPopup(leftBar);
                preventPopup(topBar);
                preventPopup(mainFrame);


                HtmlElement saveSpan = topBar.GetElementById("save_span");
                saveSpan.InvokeMember("click");

                //MessageBox.Show("Test");

            }
            catch (Exception)
            {
                appendLog("保存学习记录失败，session可能丢失，一般是网络或服务器问题！可能需要重新登录！");
            }

        }
        /// <summary>
        /// 阻止弹出窗口
        /// </summary>
        /// <param name="htmlDoc"></param>
        private void preventPopup(HtmlDocument htmlDoc)
        {
            //使用mshtml屏蔽弹出窗口
            string s = @"function confirm() {return true;}";
            s += @"function alert() {}";
            IHTMLWindow2 win = (IHTMLWindow2)htmlDoc.Window.DomWindow;
            win.execScript(s, "javascript");

            //屏蔽弹出窗口-直接注入脚本，经测试无效
            //htmlDoc.InvokeScript("window.alert = function(){}");
        }

        /// <summary>
        /// 返回字符串中指定字符中间的内容
        /// </summary>
        /// <param name="s"></param>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        /// <returns></returns>
        public string Search_string(string s, string s1, string s2)  //获取搜索到的数目
        {
            int n1, n2;
            n1 = s.IndexOf(s1, 0) + s1.Length;   //开始位置
            n2 = s.IndexOf(s2, n1);               //结束位置
            return s.Substring(n1, n2 - n1);   //取搜索的条数，用结束的位置-开始的位置,并返回
        }

        /// <summary>
        /// 返回工作区域内位置的屏幕坐标
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        private Point getPointRelativeToWB(int x, int y)
        {
            return this.PointToScreen(new Point(x, y + this.panel1.Height));
        }

        /// <summary>
        /// 使用mouse_event绝对位置控制鼠标时的坐标 
        /// </summary>
        /// <param name="ox"></param>
        /// <param name="oy"></param>
        /// <returns></returns>
        private Point getPosition(int ox, int oy)
        {
            int width = Screen.PrimaryScreen.Bounds.Width;
            int height = Screen.PrimaryScreen.Bounds.Height;

            int contentTop = this.ClientRectangle.Top + ox;
            int contentLeft = this.ClientRectangle.Left + oy;

            Point newPoint = new Point(contentTop * 65535 / width, contentLeft * 65535 / height);
            return newPoint;

        }
        /// <summary>
        /// 移除课程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            while (this.listView1.SelectedItems.Count != 0)
            {
                this.listView1.Items.Remove(this.listView1.SelectedItems[0]);
            }
            this.label4.Text = "(" + this.listView1.Items.Count.ToString() + ")";
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            this.listView1.Columns[0].Width = this.listView1.Width - 26;
        }

        /// <summary>
        /// 上移项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count == 0)
            {
                return;
            }

            listView1.BeginUpdate();
            if (listView1.SelectedItems[0].Index > 0)
            {
                foreach (ListViewItem lvi in listView1.SelectedItems)
                {
                    ListViewItem lviSelectedItem = lvi;
                    int indexSelectedItem = lvi.Index;
                    listView1.Items.RemoveAt(indexSelectedItem);
                    listView1.Items.Insert(indexSelectedItem - 1, lviSelectedItem);
                }
            }
            listView1.EndUpdate();

            if (listView1.Items.Count > 0 && listView1.SelectedItems.Count > 0)
            {
                listView1.Focus();
                listView1.SelectedItems[0].Focused = true;
                listView1.SelectedItems[0].EnsureVisible();
            }


        }
        /// <summary>
        /// 下移项
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            if (listView1.SelectedItems.Count == 0)
            {
                return;
            }

            listView1.BeginUpdate();
            int indexMaxSelectedItem = listView1.SelectedItems[listView1.SelectedItems.Count - 1].Index;

            if (indexMaxSelectedItem < listView1.Items.Count - 1)
            {
                for (int i = listView1.SelectedItems.Count - 1; i >= 0; i--)
                {
                    ListViewItem lviSelectedItem = listView1.SelectedItems[i];
                    int indexSelectedItem = lviSelectedItem.Index;
                    listView1.Items.RemoveAt(indexSelectedItem);
                    listView1.Items.Insert(indexSelectedItem + 1, lviSelectedItem);
                }
            }
            listView1.EndUpdate();

            if (listView1.Items.Count > 0 && listView1.SelectedItems.Count > 0)
            {
                listView1.Focus();
                listView1.SelectedItems[listView1.SelectedItems.Count - 1].Focused = true;
                listView1.SelectedItems[listView1.SelectedItems.Count - 1].EnsureVisible();
            }


        }

        /// <summary>
        /// 保存课程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button8_Click(object sender, EventArgs e)
        {
            string fileName = @System.Windows.Forms.Application.StartupPath + "\\MyCourse.xml";

            try
            {
                if (System.IO.File.Exists(fileName))
                {
                    System.IO.File.Delete(fileName);
                }
                XmlDocument xmlDoc = new XmlDocument();
                //创建Xml声明部分，即<?xml version="1.0" encoding="utf-8" ?>
                XmlDeclaration xmldecl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "yes");

                //创建根节点
                XmlNode rootNode = xmlDoc.CreateElement("courses");
                foreach (ListViewItem item in this.listView1.Items)
                {
                    //创建course子节点
                    XmlNode courseNode = xmlDoc.CreateElement("course");
                    //创建一个属性
                    XmlAttribute nameAttribute = xmlDoc.CreateAttribute("name");
                    nameAttribute.Value = item.Text;
                    courseNode.Attributes.Append(nameAttribute);
                    //创建一个属性
                    XmlAttribute tagAttribute = xmlDoc.CreateAttribute("tag");
                    tagAttribute.Value = item.Tag.ToString();
                    //xml节点附件属性
                    courseNode.Attributes.Append(tagAttribute);

                    rootNode.AppendChild(courseNode);
                }

                //附加根节点
                xmlDoc.AppendChild(rootNode);
                xmlDoc.InsertBefore(xmldecl, rootNode);

                //保存Xml文档
                xmlDoc.Save(fileName);

                MessageBox.Show("保存成功："+fileName);
            }
            catch (Exception)
            {
                MessageBox.Show("保存失败");
                return;
            }

        }

        /// <summary>
        /// 清空列表
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            this.listView1.Items.Clear();
            this.label4.Text = "(0)";
        }

        /* 执行鼠标点击动作
           Point ps = getPointRelativeToWB(770,300);
           SetCursorPos(ps.X, ps.Y);
           if (this.checkBox1.Checked)
           {
               mouse_event(MouseEventFlag.RightDown | MouseEventFlag.RightUp, 0, 0, 0, UIntPtr.Zero);               
           }
           else
           {
               mouse_event(MouseEventFlag.LeftDown | MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);               
           }
        */


        /// <summary>
        /// 读取保存文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            string fileName = @System.Windows.Forms.Application.StartupPath + "\\MyCourse.xml";
            if (System.IO.File.Exists(fileName))
            {
                try
                {
                    XmlDocument doc = new XmlDocument();
                    doc.Load(fileName);

                    //使用xpath表达式选择文档中所有的student子节点
                    XmlNodeList courseNodeList = doc.SelectNodes("/courses/course");
                    if (courseNodeList != null)
                    {
                        foreach (XmlNode courseNode in courseNodeList)
                        {
                            ListViewItem lvi = new ListViewItem(courseNode.Attributes["name"].Value);
                            lvi.Tag = courseNode.Attributes["tag"].Value;
                            this.listView1.Items.Add(lvi);

                        }
                    }

                    //显示共多少课
                    this.label4.Text = "(" + this.listView1.Items.Count.ToString() + ")";

                }
                catch (Exception)
                {
                    MessageBox.Show("读取文件失败！");
                    return;
                }
            }
        }

        /// <summary>
        /// 重置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button9_Click(object sender, EventArgs e)
        {
            this.webBrowser1.Dispose();

            this.webBrowser1 = new System.Windows.Forms.WebBrowser();

            this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.webBrowser1.Location = new System.Drawing.Point(0, 0);
            this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20);
            this.webBrowser1.Name = "webBrowser1";
            this.webBrowser1.ScriptErrorsSuppressed = true;

            this.panel2.Controls.Add(this.webBrowser1);

            this.webBrowser1.Navigate(@"http://learning.sinopec.com/ilearn/en/userhome/jsp/my_choose_course1.jsp");
          
            this.timer_loadPage.Enabled = false;
            this.timer_switchChapter.Enabled = false;
            this.timer_saveStudy.Enabled = false;
            this.timer_exitCourse.Enabled = false;
            this.button1.Enabled = true;

        }

        private void button10_Click(object sender, EventArgs e)
        {
            try
            {
                foreach (HtmlElement archor in this.webBrowser1.Document.Window.Frames["index_cont"].Document.Links)
                {
                    if (archor.GetAttribute("title").Contains("点击学习课程"))
                    {
                        ListViewItem lvi = new ListViewItem("《" + archor.Parent.Parent.Parent.Children[1].InnerText + "》(" + archor.Parent.Parent.Parent.Children[11].InnerText + "学分)");
                        lvi.Tag = HttpUtility.HtmlDecode(Search_string(archor.OuterHtml, "openPlayer('", "');"));
                        this.listView1.Items.Add(lvi);
                    }
                }
                //显示共多少课
                this.label4.Text = "(" + this.listView1.Items.Count.ToString() + ")";
            }
            catch (Exception)
            {
                MessageBox.Show("请先进入“我的学习”页面并等待页面完全打开");
            }
        }
    }
}
